package edu.ncut.vod.hibernate.dao.impl;

import java.util.List;

import org.hibernate.Hibernate;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import edu.ncut.vod.hibernate.dao.QuestionDao;
import edu.ncut.vod.hibernate.enhance.HibernateDaoSupportEnhance;
import edu.ncut.vod.hibernate.model.ExamType;
import edu.ncut.vod.hibernate.model.Question;

public class QuestionDaoHibernate extends HibernateDaoSupportEnhance implements
        QuestionDao,BeanPostProcessor {

    /*
     * 删除试题实体，删除一条试题记录
     * @param question 删除的试题实例
     * @see edu.ncut.vod.hibernate.dao.QuestionDao#delete(edu.ncut.vod.hibernate.model.Question)
     */
    public void delete(Question question) {
        getHibernateTemplate().delete(question);
    }

    /*
     * 根据主键删除试题实体，删除一条试题记录
     * @param id 删除试题的主键
     * @see edu.ncut.vod.hibernate.dao.QuestionDao#delete(int)
     */
    public void delete(int id) {
        getHibernateTemplate().delete(get(id));
    }

    /*
     * 根据页码查询试题列表
     * @param pageNo 查询的页码
     * @param pageSize 每页显示的试题数
     * @return 指定页的试题列表
     * @see edu.ncut.vod.hibernate.dao.QuestionDao#findAllByPage(int, int)
     */
    public List<Question> findAllByPage(int pageNo, int pageSize) {
        if (pageNo < 1) {
            return null;
        }
        int offset = (pageNo - 1) * pageSize;
        return findByPage("from Question", offset, pageSize);
    }

    /*
     * 根据试题ID、考试类型查询试题
     * @param id 需要查询的试题ID
     * @examType 考试类型
     * @return 指定ID，对应考试类型的试题
     * @see edu.ncut.vod.hibernate.dao.QuestionDao#findQuestionByExamType(int,
     * edu.ncut.vod.hibernate.model.ExamType)
     */
    public Question findQuestionByExamType(int id, ExamType examType) {
        Question question = get(id);
        // 如果指定ID已经无法获得试题，返回空
        if (question == null) {
            return null;
        }
        // 如果获得试题对应的考试类型ID与请求的考试类型的ID相同。
        if (question.getQuId() == examType.getTypeId()) {
            return question;
        }
        return null;
    }

    /*
     * 根据主键加载试题
     * @param id 需要加载的试题的主键值
     * @return 加载的试题PO
     * @see edu.ncut.vod.hibernate.dao.QuestionDao#get(int)
     */
    public Question get(int id) {
        Question q = (Question) getHibernateTemplate().load(Question.class, id);
        Hibernate.initialize(q);
        return q;
    }

    /*
     * 查询试题的最大ID
     * @return 试题的最大ID
     * @see edu.ncut.vod.hibernate.dao.QuestionDao#getMaxId()
     */
    public int getMaxId() {
        List questionList = getHibernateTemplate().find(
                "select max(question.id) from Question as question");
        if (questionList == null) {
            return 0;
        }
        return (Integer) questionList.get(0);
    }

    /*
     * 查询试题的数量
     * @return 试题的数量
     * @see edu.ncut.vod.hibernate.dao.QuestionDao#getQuestionCount()
     */
    public long getQuestionCount() {
        List questionList = getHibernateTemplate().find(
                "select count(question.id) from Question as question");
        if (questionList == null) {
            return 0;
        }
        return (Long) questionList.get(0);
    }

    /*
     * 保存试题实体，新增一条试题记录
     * @param question 保存的试题实例
     * @see edu.ncut.vod.hibernate.dao.QuestionDao#save(edu.ncut.vod.hibernate.model.Question)
     */
    public void save(Question question) {
        getHibernateTemplate().save(question);
    }

    /*
     * 更新一条试题记录
     * @param question 需要更新的试题
     * @see edu.ncut.vod.hibernate.dao.QuestionDao#update(edu.ncut.vod.hibernate.model.Question)
     */
    public void update(Question question) {
        getHibernateTemplate().update(question);
    }
    
    /**
     * this method is called on the bean just before this bean is removed from the container
     */
    public void destroy() {
        debug("destroy mothed in QuestionDaoHibernate object is called");
    }

    /**
     * this method is called on the bean immediately upon instantiation
     */
    public void setup() {
        debug("setup mothed in QuestionDaoHibernate object is called");
    }
    
    /*
     * the postProcessAfterInitialization() method is called immediately after initialization.
     * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
     */
    public Object postProcessAfterInitialization(Object arg0, String arg1)
            throws BeansException {
        debug("postProcessAfterInitialization mothed in QuestionDaoHibernate object is called");
        return null;
    }

    /*
     * The postProcessBeforeInitialization() method is called immediately prior to bean 
     * initialization (the call to afterPropertiesSet() and the bean’s custom initmethod).
     * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
     */
    public Object postProcessBeforeInitialization(Object arg0, String arg1)
            throws BeansException {
        debug("postProcessBeforeInitialization mothed in QuestionDaoHibernate object is called");
        return null;
    }
    
    /*
     * print message on console
     */
    public void debug(String message){
        System.out.println(message);
    }

}
